设计模式笔记
设计原则 S O L I D (五大设计原则)#
S -- 单一职责原则 一个程序只做好一个事 O -- 开放封闭原则 对扩展开放,对修改封闭 L -- 李氏置换原则 子类能覆盖父类 I -- 接口独立原则 保持接口独立,避免‘胖接口’ D -- 依赖倒置原则 依赖抽象,不依赖具体。 使用方只关注接口而不关注具体类的实现
创建型模式#
工厂模式#
工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象,用工厂方法代替 new 操作的一种模式。
小结:
- 构造函数和创建者分离,对 new 操作进行封装
- 符合开放封闭原则
场景#
React 的 createElement Vue 的 异步组件
单例模式#
小结:
- 单例模式的主要思想就是,实例如果已经创建,则直接返回
- 符合开放封闭原则
原型模式#
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。-- 百度百科
在 JavaScript 中,实现原型模式是在 ECMAScript5 中,提出的 Object.create 方法,使用现有的对象来提供新创建的对象的proto。
结构型模式#
适配器模式#
小结:
- 适配器模式主要解决两个接口之间不匹配的问题,不会改变原有的接口,而是由一个对象对另一个对象的包装。
- 适配器模式符合开放封闭原则
代理模式#
本文举一个使用代理对象加载图片的例子来理解代理模式,当网络不好的时候,图片的加载需要一段时间,这就会产生空白,影响用户体验,这时候我们可在图片真正加载完之前,使用一张 loading 占位图片,等图片真正加载完再给图片设置 src 属性。
本例中,本体类中有自己的 setSrc 方法,如果有一天网络速度已经不需要预加载了,我们可以直接使用本体对象的 setSrc 方法,并且不需要改动本体类的代码,而且可以删除代理类。
小结:
- 代理模式符合开放封闭原则
- 本体对象和代理对象拥有相同的方法,在用户看来并不知道请求的本体对象还是代理对象。
外观模式#
行为型模式#
装饰器模式#
装饰器 (Decorator) 是 ES7 的一个语法,是一种与类相关的语法,用来注释或修改类和类的方法。
装饰器是一种函数,写成 @ + 函数名。它可以放在类和类方法的定义前面
core-decorators.js#
@autobind:使得方法中的 this 对象,绑定原始对象 @readonly:使得属性或方法不可写。 @override:检查子类的方法,是否正确覆盖了父类的同名方法,如果不正确会报错。 @deprecate (别名 @deprecated):在控制台显示一条警告,表示该方法将废除。
观察者模式(发布 - 订阅模式) 请看《JavaScript 设计模式与开发实践》 110-124 页#
我们可以只订阅自己感兴趣的事件 就像 EventHub 可以取消订阅 也可以发布后订阅(一个存放离线事件的堆栈) 可以创建命名空间
js 中可以利用 arguments 方便的拿到注册的回调函数 来实现优雅的发布订阅模式(不需要像传统的方式需要订阅者自身提供 update 方法)
迭代器模式#
for...in 循环有几个缺点。 数组的键名是数字,但是 for...in 循环是以字符串作为键名“0”、“1”、“2”等等。 for...in 循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键。 某些情况下,for...in 循环会以任意顺序遍历键名。 总之,for...in 循环主要是为遍历对象而设计的,不适用于遍历数组。